/*
 * Klasa służy do przedstawiania punktów w kolorze zależnym od normalnych do 
 * tego punktu
 */

package nor;

import gra.TVisualisation;
import java.awt.Color;
import java.util.ArrayList;
import ste.*;
import javax.swing.*;
import krawedzie.TWykrKraw;
import out.*;
/**
 *
 * @author mignat
 */
public class TNormalne extends TAbstBlock {

    private ArrayList<TPoint[]> fPtTAL = new ArrayList<TPoint[]>();  
    private double theDist; //odleglosc pomiedzy trojkatami
    public String getTabTitle() { return "Kolorowe punkty"; }

    public JComponent getJComponent() { 
        JPanel jp = new JPanel();
        jp.setBackground(Color.YELLOW);
        jp.add(getObjP());
        return jp;   
    } //koniec getJComponent

    public void setNext(TAbstBlock aNext) { theNext = aNext; }
    
    public void checkSettings() {
        //theDist = 0.02d; //m. (pobrac parametr z okna.....)panel.get
theDist = 0.03d;
        theNext.checkSettings();
    } //koniec checkSettings

    public void showGraphic() {
        TVisualisation _lVis = new TVisualisation(); //do grafiki
        
        //Zapisuję wszystko w jednej tablicy
        ArrayList<TPoint> lPtAL = new ArrayList<TPoint>();
        for (TPoint[] ptT : fPtTAL) {//biorę kolejne tablice
            for (TPoint pt : ptT) {//biorę kolejne elty z tablicy
                lPtAL.add(pt);
                
                //Dodaję pkty otaczające dany pkt, żeby na rysunku było wyraźniej widać
                double _offset1 = 0.0025;
                lPtAL.add(new TPoint(pt.x-_offset1, pt.y, pt.z, pt.getColor()));
                lPtAL.add(new TPoint(pt.x+_offset1, pt.y, pt.z, pt.getColor()));
                
                lPtAL.add(new TPoint(pt.x, pt.y-_offset1, pt.z, pt.getColor()));
                lPtAL.add(new TPoint(pt.x, pt.y+_offset1, pt.z, pt.getColor()));
                
                lPtAL.add(new TPoint(pt.x, pt.y, pt.z-_offset1, pt.getColor()));
                lPtAL.add(new TPoint(pt.x, pt.y, pt.z+_offset1, pt.getColor()));
                
                double _offset2 = 0.005;
                lPtAL.add(new TPoint(pt.x-_offset2, pt.y, pt.z, pt.getColor()));
                lPtAL.add(new TPoint(pt.x+_offset2, pt.y, pt.z, pt.getColor()));
                
                lPtAL.add(new TPoint(pt.x, pt.y-_offset2, pt.z, pt.getColor()));
                lPtAL.add(new TPoint(pt.x, pt.y+_offset2, pt.z, pt.getColor()));
                
                lPtAL.add(new TPoint(pt.x, pt.y, pt.z-_offset2, pt.getColor()));
                lPtAL.add(new TPoint(pt.x, pt.y, pt.z+_offset2, pt.getColor()));
            }
        }
        _lVis.addPtNorT(lPtAL.toArray(new TPoint[lPtAL.size()]));
        ///_lVis.addTriangleT(theTriAL.toArray(new Tri[theTriAL.size()]));
        _lVis.display();
    } //koniec showGraphic

    public void clear() {
        fPtTAL.clear();
        theNext.clear();
    } //koniec clear

    public void starter(IOut o) {
        if (!(o instanceof TOut1_2)) return;
        TOut1_2 in = (TOut1_2) o;
        
        //Tworze tablice obiektow z jednego skanu2D
        TPoint[] ptRT = new TPoint[in.getXT().length];
        
        for (int i=0; i<ptRT.length; i++)
            ptRT[i] = new TPoint(in.getXT()[i], in.getYT()[i], in.getZT()[i]);
        
        fPtTAL.add(ptRT); //dodaje caly skan2D, jako jeden obiekt
        

    } //koniec starter
    
    public void finish() {
    
        //Ustalam kolor w zależności od normalnych
        for (int i=1; i<fPtTAL.size()-1; i++) { //skany w pionie
        //for (int i=0; i<fPtTAL.size(); i++) { //skany w pionie
            TPoint[] ptT = fPtTAL.get(i);
            //... obsłużyć skrajne odczyty 2D
            for (int j=1; j<ptT.length-1; j++) { //skany w poziomie
                if (theDist == 0d ) { //cz. biorę najbliższe sąsiedztwo
                    //       B
                    //  A    O    C
                    //       D
                    TPoint pO = ptT[j];
                    TPoint pA = ptT[j+1];
                    TPoint pB = fPtTAL.get(i+1)[j];
                    TPoint pC = ptT[j-1];
                    TPoint pD = fPtTAL.get(i-1)[j];
                    //Liczę normalną (wzgl. tego pktu, następnego i tego wyżej)
                    pO.calcNormals(pA, pB, pC, pD);
                    
                } else { //cz. biorę pkt dalej niż theDist
                    TPoint pO = ptT[j];
                    TPoint pA=null, pB=null, pC=null, pD=null;
                    
                    //2. Szukam najbliższego pktu większego niż theDist(wPrawo);
                    for (int k=j; k<ptT.length; k++) {
                        if (pO.distance(ptT[k]) > theDist) {
                            pA = ptT[k];
                            break;
                        } //koniec if
                    } //koniec for
                    if (pA==null) pA = ptT[ptT.length-1]; //gdy nie znalazłem, to biore ostatni

                    //3. Szukam najblizszego pktu wiekszego niz theDist (wGore)
                    for (int k=i; k<fPtTAL.size(); k++) {
                        TPoint _pt = fPtTAL.get(k)[j];
                        if (pO.distance(_pt) > theDist) {
                            pB = _pt;
                            break;
                        } //koniec if
                    } //koniec for
                    if (pB==null) pB = fPtTAL.get(fPtTAL.size()-1)[j]; //gdy nie znalazłem, to biore ostatni
                    
                    //4. Szukam najbliższego pktu większego niż theDist(wLewo)
                    for (int k=j; k>0; k--) {
                        if (pO.distance(ptT[k]) > theDist) {
                            pC = ptT[k];
                            break;
                        } //koniec if
                    } //koniec for
                    if (pC==null) pC = ptT[0]; //gdy nie znalazłem, to biore pierwszy
                    
                    //5. Szukam najblizszego pktu wiekszego niz theDist (wDol)
                    for (int k=i; k>0; k--) {
                        TPoint _pt = fPtTAL.get(k)[j];
                        if (pO.distance(_pt) > theDist) {
                            pD = _pt;
                            break;
                        } //koniec if
                    } //koniec for
                    if (pD==null) pD = fPtTAL.get(0)[j]; //gdy nie znalazłem, to biore pierwszy
                    
                    //Liczę normalną (wzgl. tego pktu, następnego i tego wyżej)
                    pO.calcNormals(pA, pB, pC, pD);
                } //koniec if-else                
            } //koniec for pt
        } //koniec for
        
        //przekazujemy do nastepnego motulu obiekt z policzonymi
        //juz wektrami normalnymi!
        
        ((TWykrKraw)theNext).setPtTAL(fPtTAL);
        theNext.finish(); 
        
    } //koniec finish
} //koniec konstruktora
